﻿using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using UnityEngine;
using UnityEngine.Experimental.Rendering;
using UnityEngine.Rendering;

public class CustomPipeLine : RenderPipeline
{
    private CullResults cullResults;
    private CommandBuffer cameraBuffer = new CommandBuffer()
    {
        name = "Render Camera"
    };

    private Material errorMaterial;
    
    public override void Render(ScriptableRenderContext renderContext, Camera[] cameras)
    {
        base.Render(renderContext, cameras);

        foreach (var camera in cameras)
        {
            Render(renderContext, camera);
        }
    }


    
    public void Render(ScriptableRenderContext renderContext, Camera camera)
    {
        //culling
        ScriptableCullingParameters cullingParameters;
        if (!CullResults.GetCullingParameters(camera, out cullingParameters))
        {
            return;
        }
        
#if UNITY_EDITOR
        if (camera.cameraType == CameraType.SceneView)
        {
            ScriptableRenderContext.EmitWorldGeometryForSceneView(camera);
        }
#endif
        
        //CullResults cullResults = CullResults.Cull(ref cullingParameters, renderContext);
        CullResults.Cull(ref cullingParameters, renderContext, ref cullResults); //避免每帧都创建对象cullresults 造成gc
        
        renderContext.SetupCameraProperties(camera);
        var clearFlags = camera.clearFlags;
        cameraBuffer.ClearRenderTarget((clearFlags & CameraClearFlags.Depth) != 0, (clearFlags & CameraClearFlags.Color) != 0,
            camera.backgroundColor
        );
        cameraBuffer.BeginSample("Render Camera");
        renderContext.ExecuteCommandBuffer(cameraBuffer);
        cameraBuffer.Clear();
        
        var drawSettings = new DrawRendererSettings(camera, new ShaderPassName("SRPDefaultUnlit"));
        drawSettings.sorting.flags = SortFlags.CommonOpaque;
        var filterSettings = new FilterRenderersSettings(true)
        {
            renderQueueRange = RenderQueueRange.opaque
        };
        renderContext.DrawRenderers(cullResults.visibleRenderers, ref drawSettings, filterSettings); //渲染 不透明物体
        
        renderContext.DrawSkybox(camera); // 天空盒
        
        drawSettings.sorting.flags = SortFlags.CommonTransparent;
        filterSettings.renderQueueRange = RenderQueueRange.transparent;
        renderContext.DrawRenderers(cullResults.visibleRenderers, ref drawSettings, filterSettings); //渲染 透明物体

        DrawDefaultPipeLine(renderContext, camera);
        
        cameraBuffer.EndSample("Render Camera");
        renderContext.ExecuteCommandBuffer(cameraBuffer);
        cameraBuffer.Clear();

        renderContext.Submit();
    }

    [ConditionalAttribute("DEVELOPMENT_BUILD"),ConditionalAttribute("UNITY_EDITOR")]
    public void DrawDefaultPipeLine(ScriptableRenderContext context, Camera camera)
    {
        if (errorMaterial == null)
        {
            var shader = Shader.Find("Hidden/InternalErrorShader");
            errorMaterial = new Material(shader)
            {
                hideFlags = HideFlags.HideAndDontSave
            };
        }
        
        var drawSettings = new DrawRendererSettings(camera, new ShaderPassName("ForwardBase"));
        drawSettings.SetShaderPassName(1, new ShaderPassName("PrepassBase"));
        drawSettings.SetShaderPassName(2, new ShaderPassName("Always"));
        drawSettings.SetShaderPassName(3, new ShaderPassName("Vertex"));
        drawSettings.SetShaderPassName(4, new ShaderPassName("VertexLMRGBM"));
        drawSettings.SetShaderPassName(5, new ShaderPassName("VertexLM"));
        drawSettings.SetOverrideMaterial(errorMaterial, 0);
        var filterSettings = new FilterRenderersSettings(true);
        context.DrawRenderers(cullResults.visibleRenderers, ref drawSettings, filterSettings);
    }
}
